package com.travelingsalesmen.post;

import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class Transaction {

    private static final String FORMAT = "%-20s< %d @ %8.2f>%14.2f\n";
    
    private List<Item> items = new ArrayList<Item>();
    private Payment payment;
    private String customerName;
    private double total = 0;
    private Date date;
    private IPost post;

    public Transaction() {
        this.date = new Date();
    }
    
    public void setPost(IPost post) {
        this.post = post;
    }

    public void setName(String customerName) {
        this.customerName = customerName;
    }

    public Date getDate() {
        return this.date;
    }

    public String getCustomerName() {
        return customerName;
    }

    public void setPaymentMethod(Payment payment) {
        this.payment = payment;
    }

    /**
     * Add an item to the list of items for this transaction
     *
     * @param upc UPC of the item
     * @param quantity Quantity of this item to be purchased
     * @throws NoSuchItemException If the item was not found in the product
     * catalog
     */
    public void addItem(String upc, int quantity) throws RemoteException {
        Item item = post.scanItem(upc, quantity);
        items.add(item);
        total += item.getSubtotal();   //update current total cost
    }

    /**
     * Attempt to pay
     */
    public boolean pay(Payment p) {
        payment = p;
        return p.makePayment(total);
    }

    public boolean pay(String type, String extraInfo) {
        Payment p = Payment.createPayment(type);
        p.setExtraInfo(extraInfo);
        return pay(p);
    }

    public boolean pay() {
        if (payment == null) {
            return false;
        }
        return payment.makePayment(total);
    }
    
    public String getPaymentType() {
        return payment.getClass().getSimpleName();
    }
    
    public boolean paymentWasSuccessful() {
        return payment.wasSuccessful();
    }
    
    public String getPaymentFailureReason() {
        return payment.getFailureReason();
    }

    public double getTotal() {
        return total;
    }
    
    public Invoice getInvoice() {
        // TODO implement this
        return null;
    }
    
    public List<Item> getItems() {
        return items;
    }
    
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("\tTraveling Baker\n\n");  //prints store name
        sb.append("Date: ");
        sb.append(date);
        sb.append("\n"); //prints time of transaction
        sb.append("Customer: ");
        sb.append(customerName);
        sb.append("\n");

        for (Item item : getItems()) {
            sb.append(String.format(FORMAT, item.getDescription(), item.getQty(), item.getUnitCost(), item.getSubtotal()));
        }

        sb.append("-----\n");    //separates items from payment info
        sb.append("Total $");
        sb.append(String.format("%.2f\n", total));   //amount expected to pay
        if (paymentWasSuccessful()) {
            sb.append("Payment succeeded\n");
        } else {
            sb.append("Payment failed\n");
            sb.append("Reason: ");
            sb.append(getPaymentFailureReason());
            sb.append("\n");
        }

        sb.append("\n\n");
        return sb.toString();
    }
}
